/**
 * ISO9660 test program
 */

#include <bsp.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#include <rtems.h>
#include <rtems/bdbuf.h>
#include <rtems/blkdev.h>
#include <rtems/diskdevs.h>
#include <rtems/dosfs.h>
#include <rtems/error.h>
#include <rtems/nvdisk.h>
#include <rtems/fsmount.h>
#include <rtems/ramdisk.h>
#include <rtems/shell.h>
#include <rtems/untar.h>

#include <rtems/rtems-rfs.h>
#include <rtems/rtems-rfs-format.h>
#include <rtems/rtems-rfs-shell.h>

#include <sys/types.h>
#include <dirent.h>

#include <iconv.h>
#include "iso9660.h"
#include "iso9660/iso9660_charset.h"

#if pc586
#include "pc386-gdb.h"
int remote_debug;
#endif

/*
 *  The tarfile is built automatically externally so we need to account
 *  for the leading symbol on the names.
 */
#if defined(__sh__)
  #define SYM(_x) _x
#else
  #define SYM(_x) _ ## _x
#endif

/**
 * The shell-init tarfile parameters.
 */
extern int SYM(binary_iso_collection_tar_start);
extern int SYM(binary_iso_collection_tar_size);

#define TARFILE_START SYM(binary_iso_collection_tar_start)
#define TARFILE_SIZE  SYM(binary_iso_collection_tar_size)

/* Configuration */
#include "init.h"


int
setup_rootfs (void)
{
  rtems_status_code sc;

  printf("Loading filesystem: ");

  sc = Untar_FromMemory((void *)(&TARFILE_START), (size_t)&TARFILE_SIZE);

  if (sc != RTEMS_SUCCESSFUL)
  {
    printf ("error: untar failed: %s\n", rtems_status_text (sc));
    return 1;
  }

  printf ("successful\n");

  return 0;
}

void
shell_start (void)
{
  rtems_status_code sc;
  printf ("Starting shell....\n\n");
  sc = rtems_shell_init ("fstst", 60 * 1024, 150, "/dev/console", 0, 1, NULL);
  if (sc != RTEMS_SUCCESSFUL)
    printf ("error: starting shell: %s (%d)\n", rtems_status_text (sc), sc);
}

void
iconv_test(void)
{
#define ICONV_TEST_STRING_LENGTH 15
  iso9660_fs_info_t fs;
  int i, rc;
  char strings[][ICONV_TEST_STRING_LENGTH] =
  {
      "Hello, world",
      "\xFF\xFETest\0x07"
  };

  strcpy(fs.mount_options.iocharset, "latin1");

#ifdef HAVE_ICONV
  printf("Iconv is enabled.\n");
#else
  printf("Iconv is not supported.\n");
#endif

  for (i = 0; i < sizeof(strings)/ICONV_TEST_STRING_LENGTH; i++)
  {
    char *translate = NULL;
    size_t translate_size = 0;

    printf("\nString %03d:\n", i);
    rtems_iso9660_dbg_string(strings[i], ICONV_TEST_STRING_LENGTH);

    rc = iso9660_charset_to_iocharset(strings[i], 15, &translate, &translate_size, "ucs2be", &fs);
    if (rc == -1)
      printf("Translation failed. errno=%d\n", errno);
    else
    {
      rtems_iso9660_dbg_string(translate, translate_size);
      printf("Translated string is %lu byte long at %p.\n", (unsigned long)translate_size, translate);

      free(translate);
    }
  }
}

/*
 * Entry point
 */
int
main (int argc, char* argv[])
{
  rtems_status_code sc = -1;

  #if pc586
  int arg;
  for (arg = 1; arg < argc; arg++)
    if (strcmp (argv[arg], "--gdb") == 0)
      pc386_gdb_init();
  #endif

  rtems_iso9660_dbg_set_trace(
        0
    | RTEMS_ISO9660_DEBUG_ALL
      );

  printf("\nRTEMS ISO9660 Test Version %s IDE support CPU is %s, offsets are %d/%d (32/16)\n\n",
#if RTEMS_APP_IDEDISK
   "with",
#else
   "without",
#endif
#if CPU_LITTLE_ENDIAN == TRUE
   "little-endian",
#else
   "big-endian",
#endif
   ISO9660_U32_OFFSET,
   ISO9660_U16_OFFSET
   );

  /*iconv_test();*/

  setup_rootfs();

  sc = mount_and_make_target_path("iso3.iso", "/cdrom", RTEMS_FILESYSTEM_TYPE_ISO9660,
      RTEMS_FILESYSTEM_READ_ONLY, NULL);

  if (sc != RTEMS_SUCCESSFUL)
    printf("Unable to mount iso9660 device, errno=%d (%s)\n", errno, strerror(errno));
  else
    printf("iso3.iso successfully mounted\n");

  shell_start();

  return 0;
}
